#include"PlaylistReader.h" 

#include<QByteArray>
#include<QFile>
#include<QFileInfo>

#include<stdio.h>
#include<tinyxml.h>

#include"Playlist.h"
#include"Song.h"

bool PlaylistReader::read(Playlist *playlist, const QString &path){
	QFileInfo fi(path);
	if(!fi.isFile() || !fi.isReadable())
		return false;
	if(fi.suffix().toLower() == "m3u")
		return readM3U(playlist, path);
	else if(fi.suffix().toLower() == "xml")
		return readXML(playlist, path);
	return false;
}

bool PlaylistReader::readM3U(Playlist *playlist, const QString &path){
	QFile file(path);
	if(!file.open(QIODevice::ReadOnly))
		return false;
	QString line;
	QByteArray ba;
	while(!file.atEnd()){
		ba = file.readLine();
		line = QString::fromUtf8(ba.data());
		if(line.contains('\n'))
			line.remove('\n');
		if(line.isEmpty())
			continue;
		if(line.startsWith("#Progression=")){
			if(line.endsWith("Default"))
				playlist->setProgression(TrackProgression::Default, playlist->repeatType());
			else if(line.endsWith("Random"))
				playlist->setProgression(TrackProgression::Random, playlist->repeatType());	
		}else if(line.startsWith("#Repeat=")){
			if(line.endsWith("NoRepeat"))
				playlist->setProgression(playlist->progressionType(), TrackProgression::NoRepeat);
			else if(line.endsWith("RepeatAll"))
				playlist->setProgression(playlist->progressionType(), TrackProgression::RepeatAll);
			else if(line.endsWith("RepeatOne"))
				playlist->setProgression(playlist->progressionType(), TrackProgression::RepeatOne);
		}
		if(line.startsWith('#'))
			continue;
		printf("Read line: %s\n", line.toUtf8().data());
		
		try{
			QPointer<Song> song = new Song(line);
			playlist->add(song);
		}catch(SongException){
			
		}
	}
	return true;
}

bool PlaylistReader::readXML(Playlist *playlist, const QString &path){
	QFile file(path);
	if(!file.open(QIODevice::ReadOnly))
		return false;
	QByteArray ba = file.readAll();
	
	TiXmlDocument doc;
	const char *error = doc.Parse(ba.data());
	if( (error!=0) && doc.Error() ){
		printf("Error: doc.Parse(): %s\n", error);
		return false;
	}
	TiXmlElement *rootElement = doc.RootElement();
	if(!rootElement){
		printf("Error: NULL rootElement\n");
		return false;
	}
	if(rootElement->Value() != QString("root") ){
		printf("Error: rootElement not called root\n");
		return false;
	}
	
	if(rootElement->Attribute("progression")){
		QString progression = rootElement->Attribute("progression");
		if(progression=="Default")
			playlist->setProgression(TrackProgression::Default, playlist->repeatType());
		else if(progression=="Random")
			playlist->setProgression(TrackProgression::Random, playlist->repeatType());
	}
	if(rootElement->Attribute("repeat")){
		QString repeat = rootElement->Attribute("repeat");
		if(repeat=="NoRepeat")
			playlist->setProgression(playlist->progressionType(), TrackProgression::NoRepeat);
		else if(repeat=="RepeatAll")
			playlist->setProgression(playlist->progressionType(), TrackProgression::RepeatAll);
		else if(repeat=="RepeatOne")
			playlist->setProgression(playlist->progressionType(), TrackProgression::RepeatOne);
	}
	
	for(TiXmlNode *node = rootElement->FirstChild(); node != 0; node = node->NextSibling()){
		if(node->Value() == QString("song")){
			TiXmlElement *element = node->ToElement();
			if(!element)
				continue;
			SongData data;
			data.path = QString::fromUtf8( element->Attribute("path") );
			if(data.path.isEmpty()){
				printf("Error: song with no path attribute found.\n");
				continue;
			}
			for(TiXmlNode *childNode = node->FirstChild(); childNode != 0; childNode = childNode->NextSibling() ){
				if(!childNode->ToElement())
					continue;
				QString dataString = QString::fromUtf8(childNode->ToElement()->GetText());
				if(childNode->Value() == QString("title")){
					data.title = dataString;
				}else if(childNode->Value() == QString("artist")){
					data.artist = dataString;
				}else if(childNode->Value() == QString("album")){
					data.album = dataString;
				}else if(childNode->Value() == QString("track")){
					data.trackno = dataString.toInt();
				}else if(childNode->Value() == QString("duration")){
					data.duration = dataString.toLong();
				}else 
					printf("Unknown thing %s\n", childNode->Value());
			}
			
			try{
				QPointer<Song> song = new Song(data.path, data.title, data.artist, data.album, data.trackno, data.duration);
				playlist->add(song);
			}catch(SongException){
				/*printf("Failed adding song at:\n");
				node->Print(stdout, 3);
				printf("\n");*/
				try{
					QPointer<Song> song = new Song(data.path);
					playlist->add(song);
				}catch(SongException){
					printf("Failed twice.\n");
				}
			}
		}else
			printf("Error: song not found where expected.\n");
	}
	return true;
}